/** * Copyright 2014 Jörg Prante * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xbib.logging.log4j2; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.config.plugins.PluginAttribute; import org.apache.logging.log4j.core.config.plugins.PluginFactory; import org.apache.logging.log4j.nosql.appender.NoSqlProvider; import org.apache.logging.log4j.status.StatusLogger; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.TimeValue; import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder; @Plugin(name = "Elasticsearch", category = "Core", printObject = true) public class ElasticsearchProvider implements NoSqlProvider<ElasticsearchConnection> { private static final Logger logger = StatusLogger.getLogger(); private final ElasticsearchTransportClient client; private final String description; private ElasticsearchProvider(final ElasticsearchTransportClient client, final String description) { this.client = client; this.description = "elasticsearch{ " + description + " }"; } @Override public ElasticsearchConnection getConnection() { //TODO validate client is viable return new ElasticsearchConnection(client); } @Override public String toString() { return description; } /** * Factory method for creating an Elasticsearch provider within the plugin manager. * * @param cluster The name of the Elasticsearch cluster to which log event documents will be written. * @param host The host name an Elasticsearch server node of the cluster, defaults to localhost. * @param port The port that Elasticsearch is listening on, defaults to 9300 * @param index The index that Elasticsearch shall use for indexing * @param type The type of the index Elasticsearch shall use for indexing * @return a new Elasticsearch provider */ @PluginFactory public static ElasticsearchProvider createNoSqlProvider( @PluginAttribute("cluster") String cluster, @PluginAttribute("host") String host, @PluginAttribute("port") Integer port, @PluginAttribute("index") String index, @PluginAttribute("type") String type, @PluginAttribute("timeout") String timeout, @PluginAttribute("maxActionsPerBulkRequest") Integer maxActionsPerBulkRequest, @PluginAttribute("maxConcurrentBulkRequests") Integer maxConcurrentBulkRequests, @PluginAttribute("maxVolumePerBulkRequest") String maxVolumePerBulkRequest, @PluginAttribute("flushInterval") String flushInterval) { if (cluster == null || cluster.isEmpty()) { cluster = "elasticsearch"; } if (host == null || host.isEmpty()) { host = "localhost"; } if (port == null || port == 0) { port = 9300; } if (index == null || index.isEmpty()) { index = "log4j2"; } if (type == null || type.isEmpty()) { type = "log4j2"; } if (timeout == null || timeout.isEmpty()) { timeout = "30s"; } if (maxActionsPerBulkRequest == null) { maxActionsPerBulkRequest = 1000; } if (maxConcurrentBulkRequests == null) { maxConcurrentBulkRequests = 2 * Runtime.getRuntime().availableProcessors(); } if (maxVolumePerBulkRequest == null || maxVolumePerBulkRequest.isEmpty()) { maxVolumePerBulkRequest = "10m"; } Settings settings = settingsBuilder() .put("cluster.name", cluster) .put("network.server", false) .put("node.client", true) .put("client.transport.sniff", true) .put("client.transport.ping_timeout", timeout) .put("client.transport.ignore_cluster_name", false) .put("client.transport.nodes_sampler_interval", "30s") .build(); TransportClient client = new TransportClient(settings, false); client.addTransportAddress(new InetSocketTransportAddress(host, port)); if (client.connectedNodes().isEmpty()) { logger.error("unable to connect to Elasticsearch cluster"); return null; } String description = "cluster=" + cluster + ",host=" + host + ",port=" + port + ",index=" + index + ",type=" + type; ElasticsearchTransportClient elasticsearchTransportClient = new ElasticsearchTransportClient(client, index, type, maxActionsPerBulkRequest, maxConcurrentBulkRequests, ByteSizeValue.parseBytesSizeValue(maxVolumePerBulkRequest), TimeValue.parseTimeValue(flushInterval, TimeValue.timeValueSeconds(30))); ElasticsearchProvider elasticsearchProvider = new ElasticsearchProvider(elasticsearchTransportClient, description); return elasticsearchProvider; } }